package com.sap.health.tracker;

import org.json.JSONObject;
 
import com.sap.health.tracker.json.JSONFunctions;
import com.sap.health.tracker.library.StoreData;
 
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TableRow.LayoutParams;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
 
public class RegisterActivity extends Activity implements
		AdapterView.OnItemSelectedListener{
    private Button mBtnRegister;
    private Button mBtnLinkToLogin;
    // Edit text fields for user inputs.
    private EditText mInputUserName;
    private EditText mInputFirstName;
    private EditText mInputLastName;
    private EditText mInputEmail;
    private EditText mInputAddress1;
    private EditText mInputAddress2;
    private EditText mInputCity;
    private EditText mInputState;
    private EditText mInputCountry;
    private EditText mInputPostcode;
    private EditText mInputContact;
    private EditText mInputDOB;
    private EditText mInputPassword;
    private EditText mPasswordConfirm;
    private EditText mInputBloodtype;
    private EditText mInputAllergies; 
    private CheckBox mBenchmarkCheck;
    // default to male since goes in spinner.
    private String mInputGender = "Male";
    private Spinner mGenSpin;
    private TextView mRegisterErrorMsg;
    private ArrayAdapter<CharSequence> mGenAdapter;
    // JSON Response node names
    private static String KEY_SUCCESS = "success";
    private static String KEY_UID = "uid";
    private static String KEY_SESSION = "session";
    private static String KEY_ROLE = "role";
    // loading dialog.
    private ProgressDialog mLoadingDialog;
    private Context mCtx;
    // error text views.
    private TextView mUsernameError;
    private TextView mFirstnameError;
    private TextView mPasswordError;
    private TextView mEmailError;
    private TextView mLastnameError;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.register);
        // use this context
        mCtx = this;    
        //show progress bar.
    	mLoadingDialog = new ProgressDialog(mCtx);
        mLoadingDialog.setTitle("");
        mLoadingDialog.setMessage("Loading. Please wait..."); 	        
        // Importing all assets like buttons, text fields
        mInputUserName = (EditText) findViewById(R.id.rgstUserName);
        mInputUserName.addTextChangedListener(usernameWatcher);
        mUsernameError = (TextView)findViewById(R.id.username_error);
		mUsernameError.setVisibility(View.GONE);
        
		mInputFirstName = (EditText) findViewById(R.id.rgstFirstName);
		mInputFirstName.addTextChangedListener(firstnameWatcher); 
        mFirstnameError = (TextView)findViewById(R.id.firstname_error);
		mFirstnameError.setVisibility(View.GONE);

        mInputLastName = (EditText) findViewById(R.id.rgstLastName);
        mInputLastName.addTextChangedListener(lastnameWatcher); 
        mLastnameError = (TextView)findViewById(R.id.lastname_error);
		mLastnameError.setVisibility(View.GONE);      
	    
	    mInputPassword = (EditText) findViewById(R.id.rgstPassword);
	    mInputPassword.addTextChangedListener(passwordWatcher); 
	    mPasswordError = (TextView)findViewById(R.id.password_error);
		mPasswordError.setVisibility(View.GONE);		
	    mPasswordConfirm = (EditText) findViewById(R.id.password_confirm);
	    mPasswordConfirm.addTextChangedListener(passwordConfirmWatcher);        
	    
        mInputEmail = (EditText) findViewById(R.id.registerEmail);
        mInputEmail.addTextChangedListener(emailWatcher);        
        mEmailError = (TextView)findViewById(R.id.email_error);
		mEmailError.setVisibility(View.GONE);
        
	    mInputAddress1 = (EditText) findViewById(R.id.address1);
	    mInputAddress2 = (EditText) findViewById(R.id.address2);
	    mInputCity = (EditText) findViewById(R.id.city);
	    mInputState = (EditText) findViewById(R.id.state);
	    mInputCountry = (EditText) findViewById(R.id.country);
	    mInputPostcode = (EditText) findViewById(R.id.postcode);    
	    
	    mInputContact = (EditText) findViewById(R.id.phone_number);
	    mInputAllergies = (EditText) findViewById(R.id.allergies);
	    mInputBloodtype = (EditText) findViewById(R.id.bloodType);

	    mInputDOB = (EditText) findViewById(R.id.dob);
	    mInputDOB.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {     
            	//place connection in a new thread so it doesn't stop UI            	
            	datePicker("Date of Birth");
            }
        });
	    
	    // Set listener to Spinner
        mGenSpin = (Spinner) findViewById(R.id.gender);
        mGenSpin.setOnItemSelectedListener(this);
	    // Create an ArrayAdapter using the string array, default spinner layout
	    mGenAdapter = ArrayAdapter.createFromResource(this,
	    R.array.gender_array, android.R.layout.simple_spinner_item);
	    // Specify the layout to use when the list of choices appears
	    mGenAdapter.setDropDownViewResource(
	    		android.R.layout.simple_spinner_dropdown_item);
	    // Apply the adapter to the spinner
	    mGenSpin.setAdapter(mGenAdapter);
	    
	    mBtnRegister = (Button) findViewById(R.id.btnRegister);
	    mBtnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
        mRegisterErrorMsg = (TextView) findViewById(R.id.register_error);
        
        mBenchmarkCheck = (CheckBox) findViewById(R.id.benchmark);
        
        // Register Button Click event
        mBtnRegister.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {     
            	//place connection in a new thread so it doesn't stop UI            	
            	registerThread();                	
            }
        });
 
        // Link to Login Screen
        mBtnLinkToLogin.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent i = new Intent(getApplicationContext(),
                        LoginActivity.class);
                startActivity(i);
                // Close Registration View
                finish();
            }
        });
    }
    /*
     *  Text watchers run every time a user input into the EditText field box.
     *  Checks to see if the user has inputed correct characters.
     */
    final TextWatcher usernameWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	// error should be cleared and check everything again.
            mUsernameError = (TextView)findViewById(R.id.username_error);
			mUsernameError.setVisibility(View.GONE);
			// allowed characters
        	String usernameChar = "^[a-zA-Z0-9_]*$";
        	if(mInputUserName.getText().length() < 4){
    			mUsernameError.setVisibility(View.VISIBLE);
    			mUsernameError.setText("Minimum of 4 characters for username");
        	} else if(!mInputUserName.getText().toString().matches(usernameChar)){
        		mUsernameError.setVisibility(View.VISIBLE);
    			mUsernameError.setText("Username contains illegal charactors. " +
    					"\n\n" +
    					"Only letters between a-z, A-Z, 0-9 and _ are " +
    					"accepted.");
        	}        
        }
    };
    /*
     *  Text watchers run every time a user input into the EditText field box.
     *  Checks to see if the user has inputed correct characters.
     */
    final TextWatcher firstnameWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	mFirstnameError = (TextView)findViewById(R.id.firstname_error);
    		mFirstnameError.setVisibility(View.GONE);
    		
    		if(mInputFirstName.getText().length() < 1){
    			mFirstnameError.setVisibility(View.VISIBLE);
    			mFirstnameError.setText("Firstname requires at least " +
    					"one charactor.");
        	}
        }
    };
    /*
     *  Text watchers run every time a user input into the EditText field box.
     *  Checks to see if the user has inputed correct characters.
     */
    final TextWatcher lastnameWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	// error should be cleared and check everything again.      	       	
        	mLastnameError = (TextView)findViewById(R.id.lastname_error);
    		mLastnameError.setVisibility(View.GONE);
    		if(mInputLastName.getText().length() < 1){
    			mLastnameError.setVisibility(View.VISIBLE);
    			mLastnameError.setText("Minimum of 1 character for last name");
        	}
        }
    };
    /*
     *  Text watchers run every time a user input into the EditText field box.
     *  Checks to see if the user has inputed correct characters.
     */
    final TextWatcher passwordWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	// error should be cleared and check everything again.     	       	
        	mPasswordError = (TextView)findViewById(R.id.password_error);
    		mPasswordError.setVisibility(View.GONE);
    		if(mInputPassword.getText().length() < 8){
        		mPasswordError.setVisibility(View.VISIBLE);
        		mPasswordError.setText("Minimum of 8 characters for password");
        	}
        }
    };
    /*
     *  Text watchers run every time to see if the password is the same.
     */
    final TextWatcher passwordConfirmWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	// error should be cleared and check everything again.
        	mPasswordError = (TextView)findViewById(R.id.password_error);
    		mPasswordError.setVisibility(View.GONE);  	
        	if(!mInputPassword.getText().toString().equals(
        			mPasswordConfirm.getText().toString())){
        		mPasswordError.setVisibility(View.VISIBLE);
        		mPasswordError.setText("Passwords do not match.");
        	}
        }
    };
    /*
     *  Text watchers run every time a user input into the EditText field box.
     *  Checks to see if the user has inputed correct characters.
     */
    final TextWatcher emailWatcher = new TextWatcher() {
        public void beforeTextChanged(CharSequence s, int start, int count, 
        		int after) {
        	// this function is needed but not used.
        }

        public void onTextChanged(CharSequence s, int start, int before, 
        		int count) {        	
        	// this function is needed but not used.
        }

        public void afterTextChanged(Editable s) {
        	TextView emailError = (TextView)findViewById(R.id.email_error);
    		emailError.setVisibility(View.GONE);					
    		if(mInputEmail.getText().length() < 1){
    			emailError.setVisibility(View.VISIBLE);
    			emailError.setText("Minimum of 1 characters for email");
        	}
    		if(!mInputEmail.getText().toString().contains("@") || 
    				mInputEmail.getText().toString().contains(" ")){
    			emailError.setVisibility(View.VISIBLE);
    			emailError.setText("Invalid email.");
        	}	
        }
    };
    
    private void datePicker(String title){
		  // month is 0 based, so start from 0 
    	final DatePickerDialog picker = 
    			new DatePickerDialog(mCtx, null, // null instead of a listener 
    					2000, 0, 1);
	  	// resets back to date format when picker is selected
	  	picker.setTitle(title);	
	    picker.setCancelable(true);
	    picker.setCanceledOnTouchOutside(true);
	    picker.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
	        new DialogInterface.OnClickListener() {
	            @Override
	            public void onClick(DialogInterface dialog, int which) {
	                String year = String.valueOf(
	                		picker.getDatePicker().getYear());
	                // month is 0 based, so add one.
	                String month = String.valueOf(
	                		picker.getDatePicker().getMonth()+1);
	                String day = String.valueOf(
	                		picker.getDatePicker().getDayOfMonth());
	                mInputDOB.setText(year + "-" + month + "-" + day);
	            }
	        });
		    picker.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", 
		        new DialogInterface.OnClickListener() {
		            @Override
		            public void onClick(DialogInterface dialog, int which) {
		            	// Don't need to do anything. Cancel by itself.
		            }
		        });
		    picker.show();    
	  }
    
    /*
     *  Runs when item in Spinner is selected
     */
    public void onItemSelected(AdapterView<?> parent, View view, 
            int pos, long id) {
    	// check if the correct spinner.
    	if (parent == mGenSpin){
    		switch (pos){
		    	case 0:
		    		mInputGender = "Male";
		    		break;
		    	case 1:
		    		mInputGender = "Female";
		    		break;
		    	default:
		    		mInputGender = "Male";
		    		break;
	    		}
    	}   	
    }
    // Don't do anything here.
    public void onNothingSelected(AdapterView<?> parent) {
    } 
    /*
     * Lets register the user.
     */
    public void registerThread(){
    	// if we have an error, the user wont be registered.
    	boolean error = false;				
		/*
		 *  double check that all fields are valid.
		 */
    	String usernameChar = "^[a-zA-Z0-9_]*$";
    	// once edittext has been changed, check the contents.
    	if(mInputUserName.getText().length() < 4){
			mUsernameError.setVisibility(View.VISIBLE);
			mUsernameError.setText("Minimum of 4 characters for username");
			error = true;
    	} else if(!mInputUserName.getText().toString().matches(usernameChar)){
    		mUsernameError.setVisibility(View.VISIBLE);
			mUsernameError.setText("Username contains illegal charactors. " +
					"\n\n" +
					"Only letters between a-z, A-Z, 0-9 and _ are accepted.");
			error = true;
    	} 	
    	mFirstnameError = (TextView)findViewById(R.id.firstname_error);
		mFirstnameError.setVisibility(View.GONE);		
		if(mInputFirstName.getText().length() < 1){
			mFirstnameError.setVisibility(View.VISIBLE);
			mFirstnameError.setText(
					"Firstname requires at least one charactor.");
			error = true;
    	}   	
		mLastnameError = (TextView)findViewById(R.id.lastname_error);
		mLastnameError.setVisibility(View.GONE);
		if(mInputLastName.getText().length() < 1){
			mLastnameError.setVisibility(View.VISIBLE);
			mLastnameError.setText("Minimum of 1 character for last name");
			error = true;
    	}	
		mEmailError = (TextView)findViewById(R.id.email_error);
		mEmailError.setVisibility(View.GONE);					
		if(mInputEmail.getText().length() < 1){
			mEmailError.setVisibility(View.VISIBLE);
			mEmailError.setText("Minimum of 1 characters for email");
			error = true;
    	}
		if(!mInputEmail.getText().toString().contains("@") || 
				mInputEmail.getText().toString().contains(" ")){
			mEmailError.setVisibility(View.VISIBLE);
			mEmailError.setText("Invalid email.");
			error = true;
    	}	

		mPasswordError = (TextView)findViewById(R.id.password_error);
		mPasswordError.setVisibility(View.GONE);
		if(mInputPassword.getText().length() < 8){
			mPasswordError.setVisibility(View.VISIBLE);
			mPasswordError.setText("Minimum of 8 characters for password");
    		error = true;
    	}
		if(!mInputPassword.getText().toString().equals(
				mPasswordConfirm.getText().toString())){
			mPasswordError.setVisibility(View.VISIBLE);
			mPasswordError.setText("Passwords do not match.");
    		error = true;
    	}
		TextView dobError = (TextView)findViewById(R.id.dob_error);
		dobError.setVisibility(View.GONE);
		if(mInputDOB.getText().length() < 6){
			dobError.setVisibility(View.VISIBLE);
			dobError.setText("No date of birth");
			error = true;
    	}
		// if there was nothing wrong with the inputs, then register the user.
    	if (error == false) {
    		// run on new thread so we don't lag the UI thread.
	    	new Thread(new Runnable() {	
	            @Override
	            public void run() {	            	
	            	runOnUiThread(new Runnable() {
	                    public void run() {
	                    	//progress spinner to let the user know it's busy.
	                    	mLoadingDialog.show();
	                    }
	                });
	            	// get all the user unputs.
	            	String username = mInputUserName.getText().toString();
	                String email = mInputEmail.getText().toString();
	                String password = mInputPassword.getText().toString();
	                String firstName = mInputFirstName.getText().toString();
	                String lastName = mInputLastName.getText().toString();
	              
	                String address1 = mInputAddress1.getText().toString();
	                String address2 = mInputAddress2.getText().toString();
	                String city = mInputCity.getText().toString();
	                String state = mInputState.getText().toString();
	                String country = mInputCountry.getText().toString();
	                String postcode = mInputPostcode.getText().toString();

	                String contact = mInputContact.getText().toString();
	                String dob = mInputDOB.getText().toString();
	                String allergies = mInputAllergies.getText().toString();
	                String bloodtype = mInputBloodtype.getText().toString();
	                
	                String benchmark = "";
	                if(mBenchmarkCheck.isChecked()){
	                	benchmark = "1";
	                } else {
	                	benchmark = "0";
	                }
	                
	                JSONFunctions userFunction = new JSONFunctions();
	                JSONObject json = userFunction.registerUser(username, email, 
	                		password, firstName, lastName, address1, address2,
	                		city, state, country, postcode, contact, dob,
	                		mInputGender, allergies, bloodtype, benchmark);
	 
	                // check for login response
	                try {
	                    if (json.getString(KEY_SUCCESS) != null) {          	 
	                        runOnUiThread(new Runnable() {
	                            public void run() {
	                            	// clear error messages.
	                            	mRegisterErrorMsg.setText("");
	                            }
	                        });
	                        String res = json.getString(KEY_SUCCESS);
	                        if(Integer.parseInt(res) == 1){
	                            // user successfully registered
	                            // Get user info and store it locally.
	                            JSONObject json_user = json.getJSONObject(
	                            		"user");
	                            //save session token to local storage
	                            StoreData store = new StoreData();
	                            //store user id
	                            store.saveType(mCtx, String.class, KEY_UID, 
	                            		json_user.getString(KEY_UID));
	                            //store session token
	                            store.saveType(mCtx, String.class, KEY_SESSION, 
	                            		json_user.get(KEY_SESSION));
	                            //store role type
	                            store.saveType(mCtx, String.class, KEY_ROLE, 
	                            		json_user.get(KEY_ROLE));                            
	                        	// Launch Main Screen
	                            Intent main = new Intent(
	                            		getApplicationContext(), Main.class);
	                            // Close all views before launching Dashboard
	                            main.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
	                            startActivity(main);
	                            // Close Registration Screen
	                            finish();
	                                                             
	                        } else if(Integer.parseInt(res) == 2){
	                        	runOnUiThread(new Runnable() {
	                                public void run() {
	                                	// Error in registration
	                                	mRegisterErrorMsg.setText(
	                                			"Username already taken");
	                                }
	                        	});
	                        } else if(Integer.parseInt(res) == 3){
	                        	runOnUiThread(new Runnable() {
	                                public void run() {
	                                	// Error in registration
	                                	mRegisterErrorMsg.setText(
	                                			"Email already registered");
	                                }
	                        	});
	                        } else{
	                        	runOnUiThread(new Runnable() {
	                        		public void run() {
	                        			// Error in registration
	                                	mRegisterErrorMsg.setText(
	                                			"Error occured in registration");
	                                }
	                        	});
	                        }
	                    }
	                } catch (Exception e) {
	                	//TODO catch non generic exceptions.
	                    runOnUiThread(new Runnable() {
	                        public void run() {
	                        	// Error in login
	                        	mRegisterErrorMsg.setText(
	                        			"Network Connection Error");
	                        }
	                    });
	                }
	                
	                runOnUiThread(new Runnable() {
	                    public void run() {
	                    	// show progress spinner to let the user it's busy.
	                    	mLoadingDialog.hide();
	                    }
	                });
	                
	        }
	       }).start();
    	} else {
    		// there was an error with the inputs, alert the user.
    		errorDialog("There is a problem with the inputs that " +
    				"you have entered. Please correct these before " +
    				"attempting to proceed.");
    	}
    }   
    /*
     * Show the error dialog for when something went wrong
     */
    private void errorDialog(final String message){
		
		// new dialog
		final Dialog dialog = new Dialog(mCtx);
		dialog.setContentView(R.layout.popup);
		dialog.setTitle("Input error");
		TableRow noteRow = new TableRow(mCtx);
      	// create text view.
      	TextView noteTx = new TextView(mCtx);
      	noteTx.setText(message);
      	// wrap text.
      	noteTx.setLayoutParams(new TableRow.LayoutParams(
      			LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	// add views to the row
      	noteRow.addView(noteTx);   	 
      	noteRow.setPadding(10, 10, 0, 10);
      	TableLayout dialogTable = 
      		(TableLayout) dialog.findViewById(R.id.dialogTable);    
      	// add the row to the table layout
      	dialogTable.addView(noteRow);		
		Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
		// if button is clicked, close the custom dialog
		dialogButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		dialog.show();	
	}
}


